#include "HostBase.h"
#include "NodeServer.h"
#include "eventitem.h"

int CHostBase::SendPacket(CCPacketBase* pPkg, int dst_type, int dst_svid)
{
	if (NULL != m_pNode)
		return m_pNode->SendPacket(pPkg, dst_type, dst_svid);

	return 0;
}


int CHostBase::SendPacketToService(CCPacketBase* pPkg, int dst_type, int mod_param)
{
	if (NULL != m_pNode)
		return m_pNode->SendPacketToService(pPkg, dst_type, mod_param);

	return 0;
}

int CHostBase::PushMessage(CCPacketBase* pPkg, int dst_type, int dst_svid)
{
	NETOutputPacket outPkg;
	outPkg.Begin(DISPATCH_SRV_P2P);
	outPkg.WriteShort(this->m_pNode->m_type);
	outPkg.WriteInt(TGlobal::_svid);
	outPkg.WriteShort(dst_type);
	outPkg.WriteInt(dst_svid);
	outPkg.WriteBinary(pPkg->packet_buf(), pPkg->packet_size());
	outPkg.End();

	this->SendPacket(&outPkg, SERVER_TYPE_DISPATCH);
	return 0;
}


int CHostBase::BroadcastMessage(CCPacketBase* pPkg, int dst_type)
{
	NETOutputPacket outPkg;
	outPkg.Begin(DISPATCH_SRV_BROASCAST);
	outPkg.WriteShort(this->m_pNode->m_type);
	outPkg.WriteInt(TGlobal::_svid);
	outPkg.WriteShort(dst_type);
	outPkg.WriteInt(0);
	outPkg.WriteBinary(pPkg->packet_buf(), pPkg->packet_size());
	outPkg.End();
	
	this->SendPacket(&outPkg, SERVER_TYPE_DISPATCH);
	return 0;
}


int CHostBase::PushCmd(CCPacketBase* pPkg, int cmd)
{
	NETOutputPacket outPkg;
	outPkg.Begin(DISPATCH_SRV_PUSH_CMD);
	outPkg.WriteShort(this->m_pNode->m_type);
	outPkg.WriteInt(TGlobal::_svid);
	outPkg.WriteInt(cmd);
	outPkg.WriteBinary(pPkg->packet_buf(), pPkg->packet_size());
	outPkg.End();

	this->SendPacket(&outPkg, SERVER_TYPE_DISPATCH);

	return 0;
}

int CHostBase::SendPb(SocketHandler* handler, unsigned int cmd, unsigned short dsttype, unsigned int dstid, unsigned short srctype, unsigned int srcid, const ::google::protobuf::Message* pb, bool encryp)
{
	if (!pb)
		return -1;

	string str;
	pb->SerializeToString(&str);
	NETOutputPacket outpack;
	outpack.Begin(cmd, dsttype, dstid, srctype, srcid);
	outpack.WriteBP(str.data(), str.size());
	outpack.End(encryp);
	handler->Send(&outpack);

	return 0;
}
int CHostBase::SendPb(SocketHandler* handler, unsigned int cmd, unsigned short dsttype, unsigned int dstid, const ::google::protobuf::Message* pb, bool encryp)
{
	return SendPb(handler, cmd, dsttype, dstid, m_pNode->m_type, TGlobal::_svid, pb, encryp);
}
int CHostBase::SendPb(SocketHandler* handler, unsigned int cmd, const ::google::protobuf::Message* pb, bool encryp)
{
	return SendPb(handler, cmd, handler->getType(), handler->getId(), m_pNode->m_type, TGlobal::_svid, pb, encryp);
}
int CHostBase::SendPlayerPb(SocketHandler* handler, unsigned int cmd, unsigned int uid, const ::google::protobuf::Message* pb, bool encryp)
{
	return SendPb(handler, cmd, SERVER_TYPE_GAME_PLAYER, uid, m_pNode->m_type, TGlobal::_svid, pb, encryp);
}

int CHostBase::PushPlayerMsg(unsigned int uid, unsigned int cmd, const ::google::protobuf::Message* pb, bool encryp)
{
	if (!m_pNode)
		return -1;

	string str;
	pb->SerializeToString(&str);
	NETOutputPacket pack;
	pack.Begin(cmd, SERVER_TYPE_GAME_PLAYER, uid, m_pNode->m_type, TGlobal::_svid);
	pack.WriteBP(str.data(), str.size());
	pack.End(encryp);

	m_pNode->PushPlayerMsg(uid, &pack);
	return 0;
}

int CHostBase::SendtoSrv(CCPacketBase* pPkg, unsigned short dsttype, unsigned int mod_uid)
{
	if (!m_pNode)
		return -1;

	return m_pNode->SendtoSrv(pPkg, dsttype, mod_uid);
}
int CHostBase::SendtoSrv(unsigned int cmd, unsigned short dsttype, const ::google::protobuf::Message* pb, unsigned int mod_uid, unsigned short srctype, unsigned int srcid, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	string str;
	pb->SerializeToString(&str);
	NETOutputPacket pack;
	pack.Begin(cmd, dsttype, mod_uid, srctype, srcid, seq);
	pack.WriteBP(str.data(), str.size());
	pack.End(encryp);

	return m_pNode->SendtoSrv(&pack, dsttype, mod_uid);
}

int CHostBase::SendtoSrv(unsigned int cmd, unsigned short dsttype, const ::google::protobuf::Message* pb, unsigned int mod_uid, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	return SendtoSrv(cmd, dsttype, pb, mod_uid, m_pNode->m_type, TGlobal::_svid, encryp, seq);
}

int CHostBase::SendtoOneSrv(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short dsttype, unsigned int dstid, unsigned short srctype, unsigned int srcid, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;
	if (!pb)
		return -1;

	string str;
	pb->SerializeToString(&str);
	NETOutputPacket pack;
	pack.Begin(cmd, dsttype, dstid, srctype, srcid, seq);
	pack.WriteBP(str.data(), str.size());
	pack.End(encryp);

	return m_pNode->SendPacket(&pack, dsttype, dstid);
}
int CHostBase::SendtoOneSrv(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short dsttype, unsigned int dstid, bool encryp, unsigned int seq)
{
	return SendtoOneSrv(cmd, pb, dsttype, dstid, m_pNode->m_type, TGlobal::_svid, encryp, seq);
}
int CHostBase::BroadcastMessageDirect(CCPacketBase* pPkg, const unsigned short dst_type)
{
	if (!m_pNode)
		return -1;

	return m_pNode->BroadcastMessageDirect(pPkg, dst_type);
}

int CHostBase::BroadcastMessageDirect(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short srctype, unsigned int srcid, unsigned short dsttype, bool encryp)
{
	string str;
	pb->SerializeToString(&str);
	NETOutputPacket pack;
	pack.Begin(cmd, dsttype, 0, srctype, srcid);
	pack.WriteBP(str.data(), str.size());
	pack.End(encryp);

	return BroadcastMessageDirect(&pack, dsttype);
}

int CHostBase::BroadcastMessageDirect(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short dsttype, bool encryp)
{
	return BroadcastMessageDirect(cmd, pb, m_pNode->m_type, TGlobal::_svid, dsttype, encryp);
}

int CHostBase::SendToPlayerViaAgent(const unsigned int cmd, const ::google::protobuf::Message* pb, const unsigned int uid, const unsigned int agentid, bool encryp)
{
	if (!m_pNode)
		return -1;

	string str;
	pb->SerializeToString(&str);
	NETOutputPacket pack;
	pack.Begin(cmd, SERVER_TYPE_GAME_PLAYER, uid, m_pNode->m_type, TGlobal::_svid);
	pack.WriteBP(str.data(), str.size());
	pack.End(encryp);

	m_pNode->SendPacketToSrv(&pack, SERVER_TYPE_AGENT, agentid);

	return 0;
}

int CHostBase::InitMtSend(void)
{
	if (!m_pNode)
		return -1;

	return m_pNode->InitMtSend();
}

int CHostBase::OnEventCallBack(stEventItem* pitem)
{
	if (!pitem)
		return -1;

	NETOutputPacket pack;
	pack.Begin(pitem->m_cmd, pitem->m_dsttype, pitem->m_dstsid, pitem->m_srctype, pitem->m_srcsid, pitem->m_seq);
	if (pitem->m_buff.size() > 0)
		pack.WriteBP(pitem->m_buff.data(), pitem->m_buff.size());
	pack.End(pitem->m_encryp);

	switch (pitem->m_eventid)
	{
	case EVENT_ID_1:
	{
		return m_pNode->SendtoSrv(&pack, pitem->m_dsttype, pitem->m_mod_num);
		break;
	}
	case EVENT_ID_2:
	{
		return m_pNode->SendPacketToSrv(&pack, SERVER_TYPE_AGENT, pitem->m_agentid);
		break;
	}
	case EVENT_ID_3:
	{
		return m_pNode->PushPlayerMsg(pitem->m_dstsid, &pack);
		break;
	}
	case EVENT_ID_4:
	{
		return SendPacket(&pack, pitem->m_dsttype, pitem->m_dstsid);
		break;
	}
	case EVENT_ID_5:
	{
		return BroadcastMessageDirect(&pack, pitem->m_dsttype);
		break;
	}
	default:
		break;
	}
	return 0;
}

int CHostBase::MtSendtoSrv(unsigned int cmd, unsigned short dsttype, const ::google::protobuf::Message* pb, unsigned int mod_uid, unsigned short srctype, unsigned int srcid, bool encryp, unsigned int seq)
{
	if (!(m_pNode && m_pNode->m_pSignalEvent))
		return -1;
	if (!pb)
		return -1;

	stEventItem item;
	item.m_eventid = EVENT_ID_1;
	item.m_cmd = cmd;
	item.m_dsttype = dsttype;
	item.m_srctype = srctype;
	item.m_srcsid = srcid;
	item.m_mod_num = mod_uid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	pb->SerializeToString(&item.m_buff);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtSendtoSrv(unsigned int cmd, unsigned short dsttype, const ::google::protobuf::Message* pb, unsigned int mod_uid, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	return MtSendtoSrv(cmd, dsttype, pb, mod_uid, m_pNode->m_type, TGlobal::_svid, encryp, seq);
}

int CHostBase::MtSendtoSrv(unsigned int cmd, unsigned short dsttype, std::string&& data, unsigned int mod_uid, unsigned short srctype, unsigned int srcid, bool encryp, unsigned int seq)
{
	if (!(m_pNode && m_pNode->m_pSignalEvent))
		return -1;

	stEventItem item;
	item.m_eventid = EVENT_ID_1;
	item.m_cmd = cmd;
	item.m_dsttype = dsttype;
	item.m_srctype = srctype;
	item.m_srcsid = srcid;
	item.m_mod_num = mod_uid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	item.m_buff = std::move(data);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtSendtoSrv(unsigned int cmd, unsigned short dsttype, std::string&& data, unsigned int mod_uid, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	return MtSendtoSrv(cmd, dsttype, std::move(data), mod_uid, m_pNode->m_type, TGlobal::_svid, encryp, seq);
}

int CHostBase::MtSendtoOneSrv(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short dsttype, unsigned int dstid, unsigned short srctype, unsigned int srcid, bool encryp, unsigned int seq)
{
	if (!(m_pNode && m_pNode->m_pSignalEvent))
		return -1;
	if (!pb)
		return -1;

	stEventItem item;
	item.m_eventid = EVENT_ID_4;
	item.m_cmd = cmd;
	item.m_dsttype = dsttype;
	item.m_dstsid = dstid;
	item.m_srctype = srctype;
	item.m_srcsid = srcid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	pb->SerializeToString(&item.m_buff);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtSendtoOneSrv(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short dsttype, unsigned int dstid, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	return MtSendtoOneSrv(cmd, pb, dsttype, dstid, m_pNode->m_type, TGlobal::_svid, encryp, seq);
}

int CHostBase::MtSendtoOneSrv(unsigned int cmd, std::string&& data, unsigned short dsttype, unsigned int dstid, unsigned short srctype, unsigned int srcid, bool encryp, unsigned int seq)
{
	if (!(m_pNode && m_pNode->m_pSignalEvent))
		return -1;

	stEventItem item;
	item.m_eventid = EVENT_ID_4;
	item.m_cmd = cmd;
	item.m_dsttype = dsttype;
	item.m_dstsid = dstid;
	item.m_srctype = srctype;
	item.m_srcsid = srcid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	item.m_buff = std::move(data);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtSendtoOneSrv(unsigned int cmd, std::string&& data, unsigned short dsttype, unsigned int dstid, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	return MtSendtoOneSrv(cmd, std::move(data), dsttype, dstid, m_pNode->m_type, TGlobal::_svid, encryp, seq);
}

int CHostBase::MtSendToPlayerViaAgent(const unsigned int cmd, const ::google::protobuf::Message* pb, const unsigned int uid, const unsigned int agentid, bool encryp, unsigned int seq)
{
	if (!(m_pNode && m_pNode->m_pSignalEvent))
		return -1;
	if (!pb)
		return -1;

	stEventItem item;
	item.m_eventid = EVENT_ID_2;
	item.m_cmd = cmd;
	item.m_dsttype = SERVER_TYPE_GAME_PLAYER;
	item.m_dstsid = uid;
	item.m_srctype = m_pNode->m_type;
	item.m_srcsid = TGlobal::_svid;
	item.m_agentid = agentid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	pb->SerializeToString(&item.m_buff);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtPushPlayerMsg(unsigned int uid, unsigned int cmd, const ::google::protobuf::Message* pb, bool encryp, unsigned int seq)
{
	stEventItem item;
	item.m_eventid = EVENT_ID_3;
	item.m_cmd = cmd;
	item.m_dsttype = SERVER_TYPE_GAME_PLAYER;
	item.m_dstsid = uid;
	item.m_srctype = m_pNode->m_type;
	item.m_srcsid = TGlobal::_svid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	pb->SerializeToString(&item.m_buff);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtBroadcastMessageDirect(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short srctype, unsigned int srcid, unsigned short dsttype, bool encryp, unsigned int seq)
{
	if (!(m_pNode && m_pNode->m_pSignalEvent))
		return -1;
	if (!pb)
		return -1;

	stEventItem item;
	item.m_eventid = EVENT_ID_5;
	item.m_cmd = cmd;
	item.m_dsttype = dsttype;
	item.m_srctype = srctype;
	item.m_srcsid = srcid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	pb->SerializeToString(&item.m_buff);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtBroadcastMessageDirect(unsigned int cmd, const ::google::protobuf::Message* pb, unsigned short dsttype, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	return MtBroadcastMessageDirect(cmd, pb, m_pNode->m_type, TGlobal::_svid, dsttype, encryp, seq);
}

int CHostBase::MtBroadcastMessageDirect(unsigned int cmd, std::string&& data, unsigned short srctype, unsigned int srcid, unsigned short dsttype, bool encryp, unsigned int seq)
{
	if (!(m_pNode && m_pNode->m_pSignalEvent))
		return -1;

	stEventItem item;
	item.m_eventid = EVENT_ID_5;
	item.m_cmd = cmd;
	item.m_dsttype = dsttype;
	item.m_srctype = srctype;
	item.m_srcsid = srcid;
	item.m_encryp = encryp;
	item.m_seq = seq;
	item.m_buff = std::move(data);

	m_pNode->m_pSignalEvent->add(&item);

	return 0;
}

int CHostBase::MtBroadcastMessageDirect(unsigned int cmd, std::string&& data, unsigned short dsttype, bool encryp, unsigned int seq)
{
	if (!m_pNode)
		return -1;

	return MtBroadcastMessageDirect(cmd, std::move(data), m_pNode->m_type, TGlobal::_svid, dsttype, encryp, seq);
}